﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Configuration;

namespace ProjectSchedule.Common
{
    public class Logger
    {
        private static readonly Lazy<Logger> _instance = new Lazy<Logger>(() => new Logger());
        public static Logger Instance
        {
            get
            {
                return _instance.Value;
            }
        }

        #region 构造函数
        private Logger()
        {
            this._logPath =AppDomain.CurrentDomain.BaseDirectory+@"Log\";
            this._fileExtName = "log";
            this._fileEncoding = Encoding.UTF8;
            this._enabledLog = (ConfigurationManager.AppSettings["EnabledLog"] ?? String.Empty).ToUpper().Equals("ON");
            this._logLevel = ConfigurationManager.AppSettings["EnabledDebug"] ?? "Info";
            if (!Enum.TryParse<LogType>(this._logLevel, true, out this._logType))
            {
                this._logType = LogType.Info;
            }
        }
        #endregion

        #region 字段和属性
        private bool _enabledLog;
        private string _logLevel;
        private LogType _logType;
        private string _fileName;
        private string _logPath;
        private string _fileExtName;
        private Encoding _fileEncoding;
        private object obj = new object();

        /// <summary>
        /// Log 文件路径
        /// </summary>
        public string LogPath
        {
            get
            {
                return this._logPath;
            }
            set
            {
                _logPath = value;
            }
        }

        /// <summary>
        /// Log 文件扩展名
        /// </summary>
        public string FileExtName
        {
            get { return this._fileExtName; }
            set { this._fileExtName = value; }
        }

        /// <summary>
        /// 日志文件的字符编码
        /// </summary>
        public Encoding FileEncoding
        {
            get { return _fileEncoding; }
            set { _fileEncoding = value; }
        }
        #endregion

        #region 公有方法
        public void OnWriteLog(LogType logType, string msg)
        {
            lock (obj)
            {
                try
                {
                    if (!this._enabledLog) return;
                    if (logType < this._logType) return;

                    _fileName = _logPath +"Log_"+ DateTime.Now.ToString("yyyyMMdd")+"." + _fileExtName;
                    using (StreamWriter sw = new StreamWriter(_fileName, true, _fileEncoding))
                    {
                        sw.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss: ") + logType.ToString() + " " + msg);
                    }
                }
                catch (Exception)
                {
                }
            }
        }


        /// <summary>
        /// 调试
        /// </summary>
        /// <param name="msg"></param>
        public void Debug(string msg)
        {
            this.OnWriteLog(LogType.Debug, msg);
        }

        /// <summary>
        /// 信息
        /// </summary>
        /// <param name="msg"></param>
        public void Info(string msg)
        {
            this.OnWriteLog(LogType.Info, msg);
        }

        /// <summary>
        /// 错误
        /// </summary>
        /// <param name="msg"></param>
        public void Error(string msg,Exception ex=null)
        {
            this.OnWriteLog(LogType.Error, msg+ExceptionString(ex));
        }

        private String ExceptionString(Exception ex)
        {
            if (ex == null) return String.Empty;
            return String.Format("\r\n Method:{0}; Message:{1}; Source:{2}; StackTrace:{3}",
                ex.TargetSite, ex.Message, ex.Source, ex.StackTrace);
        }
        #endregion
    }

    public enum LogType
    {
        Debug,
        Info,
        Warn,
        Error
    }

}
